package light.mvc.service.doctor.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import light.mvc.dao.BaseDaoI;
import light.mvc.model.item.Tmedicine;
import light.mvc.model.register.TmedicinePrescription;
import light.mvc.model.register.Tprescription;
import light.mvc.model.register.Tregister;
import light.mvc.page.doctor.MedicinePrescription;
import light.mvc.page.doctor.Prescription;
import light.mvc.service.doctor.RegisterMedicineServiceI;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RegisterMedicineServiceImpl implements RegisterMedicineServiceI {

	@Autowired
	private BaseDaoI<Tregister> registerDao;
	
	@Autowired
	private BaseDaoI<Tprescription> prescriptionDao;
	
	@Autowired 
	private BaseDaoI<Tmedicine> medicineDao;
	
	@Autowired 
	private BaseDaoI<TmedicinePrescription> medicinePrescriptionDao;

	@Override
	public Prescription getPrescription(Integer registerId) {
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("registerId", registerId);
		
		String hql = "select t from Tregister register join register.prescription t " +
					"where register.id = :registerId";
		Tprescription t = prescriptionDao.get(hql,params);
		
		List<MedicinePrescription> medicinePrescriptions = new ArrayList<MedicinePrescription>(0);
		Prescription prescription = new Prescription();
		
		if(t == null) {
			hql = "from Tmedicine t";
			List<Tmedicine> medicines = medicineDao.find(hql);
			for(Tmedicine medicine:medicines) {
				MedicinePrescription medicinePrescription = new MedicinePrescription();
				BeanUtils.copyProperties(medicine,medicinePrescription);
				medicinePrescriptions.add(medicinePrescription);
			}
		} else {
			Set<TmedicinePrescription> tMedicinePrescriptions = t.getMedicinePrescriptions();
			prescription.setAddTime(t.getAddTime());
			prescription.setChargeTime(t.getChargeTime());
			prescription.setMedicineTime(t.getMedicineTime());
			prescription.setSumPrice(t.getSumPrice());
			
			for(TmedicinePrescription tMedicinePrescription : tMedicinePrescriptions) {
				MedicinePrescription medicinePrescription = new MedicinePrescription();
			
				Tmedicine tMedicine = tMedicinePrescription.getMedicine();
				BeanUtils.copyProperties(tMedicine,medicinePrescription);
				
				medicinePrescription.setMedicineNum(tMedicinePrescription.getMedicineNum());
				
				medicinePrescriptions.add(medicinePrescription);
			}
		}
		prescription.setMedicinePrescriptions(medicinePrescriptions);
		return prescription;
	}
	
	@Override
	public List<MedicinePrescription> getPrescriptionByPatientId(Integer patientId,Date timeSegment) {
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("patientId", patientId);
		
		String hql = "select register from Tregister register " +
					"join register.patient patient where patient.id = :patientId ";
		if(timeSegment != null) {
			params.put("timeSegment", timeSegment);
			hql += "and register.timeSegment = :timeSegment";
		}
		List<Tregister> registers = registerDao.find(hql,params);
		
		List<MedicinePrescription> medicinePrescriptions = new ArrayList<MedicinePrescription>(0);
		
		for(Tregister t : registers) {
			if(t.getPrescription() == null) {
				continue;
			}
			Set<TmedicinePrescription> tMedicinePrescriptions = t.getPrescription().getMedicinePrescriptions();
			
			boolean first = true;
			for(TmedicinePrescription tMedicinePrescription : tMedicinePrescriptions) {
				MedicinePrescription medicinePrescription = new MedicinePrescription();
				
				if(first) {
					medicinePrescription.setAddTime(t.getPrescription().getAddTime());
					medicinePrescription.setChargeTime(t.getPrescription().getChargeTime());
					medicinePrescription.setMedicineTime(t.getPrescription().getMedicineTime());
					medicinePrescription.setSumPrice(t.getPrescription().getSumPrice());
					
					medicinePrescription.setTimeSegment(t.getTimeSegment());
					medicinePrescription.setSeq(t.getSeq());
					medicinePrescription.setDepartmentName(t.getDoctor().getDepartment().getName());
					medicinePrescription.setDoctorName(t.getDoctor().getName());
					first = false;
				}
				
				medicinePrescription.setName(tMedicinePrescription.getMedicine().getName());	
				medicinePrescription.setMedicineNum(tMedicinePrescription.getMedicineNum());
				medicinePrescription.setPrice(tMedicinePrescription.getMedicine().getPrice());
	
				medicinePrescriptions.add(medicinePrescription);
			}

		}
		return medicinePrescriptions;
	}
	
	@Override
	public void addPrescription(Integer registerId,List<MedicinePrescription> medicinePrescriptions) throws Exception{
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("registerId", registerId);
		
		String hql = "from Tregister register " +
					"where register.id = :registerId";
		Tregister register = registerDao.get(hql,params);

		if(register.getPrescription() != null) {
			if(register.getPrescription().getChargeTime() == null) {
				prescriptionDao.delete(register.getPrescription());
			} else {
				throw new Exception("已缴费");
			}
		}
		
		Tprescription prescription = new Tprescription();
		prescription.setAddTime(new Date());
		
		prescription.setId((Integer)prescriptionDao.save(prescription));
		
		Double sumPrice = 0.0;
		for(MedicinePrescription medicinePrescription:medicinePrescriptions) {
			Tmedicine medicine = medicineDao.get(Tmedicine.class, medicinePrescription.getId());
			
			TmedicinePrescription tMedicinePrescription = new TmedicinePrescription();
			tMedicinePrescription.setPrescription(prescription);
			tMedicinePrescription.setMedicine(medicine);
			tMedicinePrescription.setMedicineNum(medicinePrescription.getMedicineNum());
			
			sumPrice += medicine.getPrice() * medicinePrescription.getMedicineNum();
			
			medicinePrescriptionDao.save(tMedicinePrescription);
		}
		
		prescription.setSumPrice(sumPrice);
		prescriptionDao.update(prescription);
		

		register.setPrescription(prescription);
		registerDao.update(register);
	
	}
	
	@Override
	public void deletePrescription(Integer registerId) throws Exception{
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("registerId", registerId);
		
		String hql = "from Tregister register " +
					"where register.id = :registerId";
		Tregister register = registerDao.get(hql,params);
		Tprescription t = register.getPrescription();
		if(t == null) {
			throw new Exception("没有旧药单,可直接开单");
		}
		if(t.getChargeTime() != null) {
			throw new Exception("已缴费");
		} else if(t.getMedicineTime() != null) {
			throw new Exception("已取药");
		}
		
		for(TmedicinePrescription tMedicinePrescription : t.getMedicinePrescriptions()) {
			medicinePrescriptionDao.delete(tMedicinePrescription);
		}
		
		prescriptionDao.delete(t);
	
	}
	
	@Override
	public void charge(Integer registerId) throws Exception{
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("registerId", registerId);
		
		String hql = "from Tregister register " +
					"where register.id = :registerId";
		Tregister register = registerDao.get(hql,params);
		Tprescription t = register.getPrescription();
		
		if(t.getChargeTime() != null) {
			throw new Exception("已缴费");
		}
		
		t.setChargeTime(new Date());
		
		prescriptionDao.update(t);
		
	}
	
	@Override
	public void takeMedicine(Integer registerId) throws Exception{
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("registerId", registerId);
		
		String hql = "from Tregister register " +
					"where register.id = :registerId";
		Tregister register = registerDao.get(hql, params);
		Tprescription t = register.getPrescription();
		if(t.getChargeTime() == null) {
			throw new Exception("尚未缴费");
		} else if(t.getMedicineTime() != null) {
			throw new Exception("已取药");
		}
		
		t.setMedicineTime(new Date());
		
		prescriptionDao.update(t);
	}
}
